package router

import (
	"fmt"
	"io/ioutil"
	"iptables-admin/common"
	"iptables-admin/pkg/iptables"
	"iptables-admin/utils"
	"log"
	"os/exec"
	"runtime"
	"strings"

	"github.com/gin-gonic/gin"
)

type Router struct {
}

type Resp struct {
	Code int         `json:"code"`
	Data interface{} `json:"data"`
	Mag  string      `json:"msg"`
}

func NewRouter() Router {
	return Router{}
}

func (a *Router) Version(ctx *gin.Context) {
	ipc, err := iptables.NewIPV4()
	if err != nil {
		fmt.Println(err)
	}
	v, err := ipc.Version()
	os := runtime.GOOS
	goarch := runtime.GOARCH

	data := make(map[string]string)
	data["iptables_version"] = v
	data["os"] = os
	data["goarch"] = goarch
	data["kernel"] = getKernelDetail()

	if err != nil {
		fmt.Println(err)
		ctx.JSON(200, common.Error(201, "系统异常"))
		return
	}
	ctx.JSON(200, common.OK(data))
}

func getKernelDetail() string {
	cmd := exec.Command("uname", "-a")
	stdout, err := cmd.StdoutPipe()
	fmt.Println(stdout)
	if err != nil {
		log.Fatal(err)
	}
	defer stdout.Close()
	if err := cmd.Start(); err != nil {
		log.Fatal(err)
	}
	opBytes, err := ioutil.ReadAll(stdout)
	if err != nil {
		log.Fatal(err)
	}
	getVersion01 := fmt.Sprintf("%s", string(opBytes))
	getVersion := strings.Split(getVersion01, " ")
	return getVersion[2]
}

func (a *Router) ListRule(ctx *gin.Context) {
	ipc, err := iptables.NewIPV4()
	if err != nil {
		fmt.Println(err)
	}
	table := ctx.DefaultQuery("table", "")
	chain := ctx.DefaultQuery("chain", "")
	l, err := ipc.ListRule(table, chain)
	if err != nil {
		fmt.Println(err)
		ctx.JSON(200, common.Error(201, "系统异常"))
		return
	}
	ctx.JSON(200, common.OK(l))
}

func (a *Router) ListExec(ctx *gin.Context) {
	ipc, err := iptables.NewIPV4()
	if err != nil {
		fmt.Println(err)
	}
	table := ctx.DefaultQuery("table", "")
	chain := ctx.DefaultQuery("chain", "")
	l, err := ipc.ListExec(table, chain)
	if err != nil {
		fmt.Println(err)
		ctx.JSON(200, common.Error(201, "系统异常"))
		return
	}
	ctx.JSON(200, common.OK(l))
}

func (a *Router) FlushRule(ctx *gin.Context) {
	ipc, err := iptables.NewIPV4()
	if err != nil {
		fmt.Println(err)
	}
	table := ctx.DefaultQuery("table", "")
	chain := ctx.DefaultQuery("chain", "")
	err = ipc.FlushRule(table, chain)
	if err != nil {
		fmt.Println(err)
		ctx.JSON(200, common.Error(201, "系统异常"))
		return
	}
	ctx.JSON(200, common.OK(""))
}

func (a *Router) DeleteRule(ctx *gin.Context) {
	ipc, err := iptables.NewIPV4()
	if err != nil {
		fmt.Println(err)
	}
	table := ctx.DefaultQuery("table", "")
	chain := ctx.DefaultQuery("chain", "")
	id := ctx.DefaultQuery("id", "")
	err = ipc.DeleteRule(table, chain, id)
	if err != nil {
		fmt.Println(err)
		ctx.JSON(200, common.Error(201, "系统异常"))
		return
	}
	ctx.JSON(200, common.OK(""))
}

func (a *Router) FlushMetrics(ctx *gin.Context) {
	ipc, err := iptables.NewIPV4()
	if err != nil {
		fmt.Println(err)
	}
	table := ctx.DefaultQuery("table", "")
	chain := ctx.DefaultQuery("chain", "")
	id := ctx.DefaultQuery("id", "")
	err = ipc.FlushMetrics(table, chain, id)
	if err != nil {
		fmt.Println(err)
		ctx.JSON(200, common.Error(201, "系统异常"))
		return
	}
	ctx.JSON(200, common.OK(""))
}

func (a *Router) GetRuleInfo(ctx *gin.Context) {
	ipc, err := iptables.NewIPV4()
	if err != nil {
		fmt.Println(err)
	}
	table := ctx.DefaultQuery("table", "")
	chain := ctx.DefaultQuery("chain", "")
	id := ctx.DefaultQuery("id", "")
	info, err := ipc.GetRuleInfo(table, chain, id)
	if err != nil {
		fmt.Println(err)
		ctx.JSON(200, common.Error(201, "系统异常"))
		return
	}
	ctx.JSON(200, common.OK(info))
}

func (a *Router) FlushEmptyCustomChain(ctx *gin.Context) {
	ipc, err := iptables.NewIPV4()
	if err != nil {
		fmt.Println(err)
	}
	err = ipc.FlushEmptyCustomChain()
	if err != nil {
		fmt.Println(err)
		ctx.JSON(200, common.Error(201, "系统异常"))
		return
	}
	ctx.JSON(200, common.OK(""))
}

func (a *Router) Export(ctx *gin.Context) {
	ipc, err := iptables.NewIPV4()
	if err != nil {
		fmt.Println(err)
	}
	table := ctx.DefaultQuery("table", "")
	chain := ctx.DefaultQuery("chain", "")
	rule, err := ipc.Export(table, chain)
	if err != nil {
		fmt.Println(err)
		ctx.JSON(200, common.Error(201, "系统异常"))
		return
	}
	ctx.JSON(200, common.OK(rule))
}

func (a *Router) Import(ctx *gin.Context) {
	ipc, err := iptables.NewIPV4()
	if err != nil {
		fmt.Println(err)
	}
	rule := ctx.DefaultQuery("rule", "")
	err = ipc.Import(rule)
	if err != nil {
		fmt.Println(err)
		ctx.JSON(200, common.Error(201, "系统异常"))
		return
	}
	ctx.JSON(200, common.OK(""))
}

func (a *Router) Exec(ctx *gin.Context) {
	ipc, err := iptables.NewIPV4()
	if err != nil {
		fmt.Println(err)
	}
	args := ctx.DefaultQuery("args", "")
	s := utils.SplitAndTrimSpace(args, " ")
	str, err := ipc.Exec(s...)
	if err != nil {
		fmt.Println(err)
		ctx.JSON(200, common.Error(201, "系统异常"))
		return
	}
	ctx.JSON(200, common.OK(str))
}
